﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using ExcellData;
using ExcelUtilitiesFactory;
using SiGeSIB.Data.Finances;
using SiGeSIB.Data.Common;

namespace SiGeSIB.Business.Impl
{
	public partial class ReportController
	{
		private IExcelIntegration _ExcelIntegration;

		public ReportController()
		{
			_ExcelIntegration = ExcelFactory.CreateExcelIntegration();
		}

		#region IReportManager Members

		public void GenerateReport(List<CostCenter> centros, string filePath, EMovimentationType type, DateTimeInterval interval)
		{
			IWorkbook workbook = _ExcelIntegration.CreateWorkbook(Type.Missing);

			// Renomeando a planilha principal
			IWorksheet sheet = workbook.ActiveSheet;
			sheet.Name = "Relatório";

			#region Deletando as outras planilhas
			foreach (IWorksheet defaultSheet in workbook.Sheets)
			{
				if (defaultSheet.Name != "Relatório")
					defaultSheet.Delete();
			}
			#endregion

			int rowsCount = 2;
			int fixRowsCount = 3;
			int fixColumnsCount = 3;

			IExcelRange fileHeaderRange = sheet.get_Range("A1", Missing.Value);
			fileHeaderRange = fileHeaderRange.get_Resize(1, fixColumnsCount);
			fileHeaderRange.Merge();
			string header = "Relatório de "+ (type == EMovimentationType.Income ? "entradas" : type == EMovimentationType.Outcome ? "saídas" : "lançamentos futuros");
			header += " (" + interval.ToString()+")";
			fileHeaderRange.set_Value(header);

			foreach (CostCenter centro in centros)
			{
				if (centro.Movimentations != null && centro.Movimentations.Count > 0)
				{
					IExcelRange range = sheet.get_Range("A" + (rowsCount + 1), Missing.Value);
					range = range.get_Resize(centro.Movimentations.Count + fixRowsCount, fixColumnsCount);

					object[,] values = new object[centro.Movimentations.Count + fixRowsCount, fixColumnsCount];

					values[0, 0] = centro.Name;
					values[1, 0] = type == EMovimentationType.Income ? "Origem" : type == EMovimentationType.Outcome  ? "Beneficiado" : "Contribuinte";
					values[1, 1] = "Valor (R$)";
					values[1, 2] = "Observação";

					decimal total = 0M;

					for (int i = 0; i < centro.Movimentations.Count; i++)
					{
						Movimentation movimentacao = centro.Movimentations[i];
						decimal amount = movimentacao.Type == EMovimentationType.Income ? movimentacao.Amount : (-movimentacao.Amount);
						values[i + 2, 0] = movimentacao.Contributor.Name;
						values[i + 2, 1] = amount;
						values[i + 2, 2] = movimentacao.Observation;

						total += amount;
					}
					values[centro.Movimentations.Count + fixRowsCount - 1, 0] = "Total";
					values[centro.Movimentations.Count + fixRowsCount - 1, fixColumnsCount-1] = total;

					range.set_Value(values);

					// Mescla as células da linha do título
					IExcelRange titleRange = range.get_Resize(1,fixColumnsCount);
					titleRange.Merge();

					// Mescla as células da linha do total
					IExcelRange totalRange = sheet.get_Range("A" + (rowsCount + centro.Movimentations.Count + fixRowsCount), Missing.Value);
					totalRange = totalRange.get_Resize(1, fixColumnsCount - 1);
					totalRange.Merge();

					// Auto-ajusta a largura das colunas
					range.AutoFit();

					// Alinha todos à esquerda
					range.HorizontalAlignment = EExcelHorizontalAlign.Left;
					
					// Aplica bordas ao range
					range.FillBorders(EExcelLineStyle.Continuous, EExcelBorderWeight.Thin);
					range.BorderAround(EExcelLineStyle.Continuous, EExcelBorderWeight.Medium);

					// Alinha a coluna de valores à direita
					IExcelRange valuesColumn = sheet.get_Range("B2", Missing.Value);
					valuesColumn.EntireColumn.HorizontalAlignment = EExcelHorizontalAlign.Right;

					// Pega o range das 2 primeiras linhas (cabeçalho)
					IExcelRange headerRange = range.get_Resize(2, fixColumnsCount);
					// Centraliza
					headerRange.HorizontalAlignment = EExcelHorizontalAlign.Center;
					headerRange.FillBorders(EExcelLineStyle.Continuous, EExcelBorderWeight.Medium);

					if (centro.Movimentations != null)
						rowsCount += centro.Movimentations.Count + fixRowsCount + 1;
				}
			}

			sheet.SaveAs(filePath);
			#region Encerrando o excel
			workbook.Close();
			#endregion
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			_ExcelIntegration.Quit();
			GC.Collect();
		}

		#endregion
	}
}
